﻿using System;
using System.Linq;
using Microsoft.SharePoint;

namespace Xodeuz.SP.Common
{
    /// <summary>
    /// Base SPListItem Model Object
    /// </summary>
    [ContentType("0x01", "Item")]
    public class ListItemModelBase
    {
        [Field("ID", SPFieldType.Counter)]
        public int ItemId { get; set; }

        [Field("Title", SPFieldType.Text)]
        public string Title { get; set; }

        [Field("Created", SPFieldType.DateTime)]
        public DateTime Created { get; set; }

        [Field("Author", SPFieldType.User)]
        public string CreatedBy { get; set; }

        [Field("Modified", SPFieldType.DateTime)]
        public DateTime Modified { get; set; }

        [Field("Editor", SPFieldType.User)]
        public string ModifiedBy { get; set; }

        [Field("FileLeafRef", SPFieldType.Text)]
        public string FileLeafRef { get; set; }

        [Field("FileDirRef", SPFieldType.Text)]
        public string FileDirRef { get; set; }

        public Guid ListId { get; set; }
        public Guid WebId { get; set; }
        public Guid SiteId { get; set; }
       
        public ListItemModelBase(){}

        public ListItemModelBase(Guid siteId, Guid webId, Guid listId)
        {
            this.SiteId = siteId;
            this.WebId = webId;
            this.ListId = listId;
        }


        /// <summary>
        /// Submit Changes to List (SiteID, WebID and ListID required for new items)
        /// </summary>
        /// <param name="elevatedPermissions"></param>
        public void SubmitChanges(bool elevatedPermissions = false)
        {
            if (elevatedPermissions)
            {
                SPSecurity.RunWithElevatedPrivileges(delegate
                {
                    using (SPSite site = new SPSite(SiteId))
                    using (SPWeb web = site.OpenWeb(WebId))
                    {
                        SubmitItemChanges(web);
                    }
                });
            }
            else
            {
                SubmitItemChanges(SPContext.Current.Web);
            }
        }

        public void SubmitChanges(Guid siteId, Guid webId, Guid listId, bool elevatedPermissions = false)
        {
            this.SiteId = siteId;
            this.WebId = webId;
            this.ListId = ListId;

            SubmitChanges(elevatedPermissions);
        }

        private void SubmitItemChanges(SPWeb web)
        {
            var internalNames = ReflectionService.GetPropertyNameWithCustomAttribute<Field>(GetType());
            var list = web.Lists[ListId];
            var item = ItemId != 0 ? list.GetItemById(ItemId) : list.Items.Add();
            var properties = ReflectionService.PublicPropertyInfos(GetType());

            foreach (var property in properties)
            {
                if (!internalNames.ContainsKey(property.Name)) continue;

                var fieldName = internalNames[property.Name];

                if(ReadOnly.Fields.Contains(fieldName.InternalName)) continue;

                item[fieldName.InternalName] = property.GetValue(this, null);
            }

            item.Update();
        }
    }
}
